<!--
 * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available.
 *
 * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
 *
 * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License.
 *
 * License for BK-JOB蓝鲸智云作业平台:
 *
 *
 * Terms of the MIT License:
 * ---------------------------------------------------
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
 * the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
-->

<template>
  <div class="script-source-of-execution">
    <jb-form-item
      class="script-source-item"
      :label="$t('脚本来源')"
      required>
      <bk-radio-group
        :value="scriptSource"
        @change="handleScriptSourceChange">
        <bk-radio-button value="local">
          {{ $t('手工录入') }}
        </bk-radio-button>
        <bk-radio-button value="refer">
          {{ $t('脚本引用') }}
        </bk-radio-button>
      </bk-radio-group>
    </jb-form-item>
    <jb-form-item
      v-if="isScriptRefer"
      ref="scriptId"
      :label="$t('脚本引用')"
      property="scriptId"
      required
      :rules="rules">
      <div class="form-item-content refer-script-box">
        <compose-form-item>
          <bk-select
            :clearable="false"
            style="width: 120px;"
            :value="referType"
            @change="handleReferScriptTypeChange">
            <bk-option
              :id="2"
              :name="$t('业务脚本')">
              {{ $t('业务脚本') }}
            </bk-option>
            <bk-option
              :id="3"
              :name="$t('公共脚本')">
              {{ $t('公共脚本') }}
            </bk-option>
          </bk-select>
          <bk-select
            :key="referType"
            class="refer-script-list"
            :clearable="false"
            :placeholder="$t('选择引用脚本')"
            searchable
            :value="formData[scriptVersionIdField]"
            @change="handleScriptVersionIdChange"
            @toggle="handleClick">
            <auth-option
              v-for="option in scripListDisplay"
              :id="option.scriptVersionId"
              :key="option.scriptVersionId"
              :auth="authView"
              :name="option.name"
              :permission="option.canView"
              :resource-id="option.id" />
            <template slot="extension">
              <auth-component :auth="authCreate">
                <div
                  style="cursor: pointer;"
                  @click="handleGoCreate">
                  <i class="bk-icon icon-plus-circle mr10" />{{ newBtnText }}
                </div>
                <div slot="forbid">
                  <i class="bk-icon icon-plus-circle mr10" />{{ newBtnText }}
                </div>
              </auth-component>
            </template>
          </bk-select>
        </compose-form-item>
        <div
          v-if="formData[scriptVersionIdField]"
          class="refer-script-detail"
          :tippy-tips="$t('脚本详情')"
          @click="handleGoScriptDetail">
          <icon type="jump" />
        </div>
      </div>
    </jb-form-item>
  </div>
</template>
<script>
  import PublicScriptService from '@service/public-script-manage';
  import ScriptService from '@service/script-manage';

  import TaskStepModel from '@model/task/task-step';

  import ComposeFormItem from '@components/compose-form-item';

  import I18n from '@/i18n';

  export default {
    components: {
      ComposeFormItem,
    },
    props: {
      // 脚本来源字段名
      scriptSourceField: {
        type: String,
        required: true,
      },
      // 脚本id字段名
      scriptIdField: {
        type: String,
        required: true,
      },
      // 脚本版本id字段名
      scriptVersionIdField: {
        type: String,
      },
      // 脚本内容字段名
      contentField: {
        type: String,
        required: true,
      },
      // 脚本语言字段名
      languageField: {
        type: String,
        required: true,
      },
      formData: {
        type: Object,
        default: () => ({}),
      },
    },
    data() {
      return {
        scripList: [],
        publicScripList: [],
        scriptSource: 'local',
        referType: 2,
      };
    },
    computed: {
      /**
       * @desc 使用脚本资源需要的权限
       * @returns {String}
       */
      authView() {
        return this.formData[this.scriptSourceField] === TaskStepModel.scriptStep.TYPE_SOURCE_BUSINESS
          ? 'script/view'
          : 'public_script/view';
      },
      /**
       * @desc 脚本新建的权限
       * @returns { String }
       */
      authCreate() {
        return this.formData[this.scriptSourceField] === TaskStepModel.scriptStep.TYPE_SOURCE_BUSINESS
          ? 'script/create'
          : 'public_script/create';
      },
      /**
       * @desc 引用脚本类型
       * @returns { Boolean }
       */
      isScriptRefer() {
        return this.scriptSource === 'refer';
      },
      /**
       * @desc 脚本列表
       * @returns { Array }
       */
      scripListDisplay() {
        const scriptSource = this.formData[this.scriptSourceField];

        if (scriptSource === TaskStepModel.scriptStep.TYPE_SOURCE_BUSINESS) {
          return this.scripList;
        }
        if (scriptSource === TaskStepModel.scriptStep.TYPE_SOURCE_PUBLIC) {
          return this.publicScripList;
        }
        return [];
      },
      /**
       * @desc 按钮的文本
       * @returns { String }
       */
      newBtnText() {
        return this.formData[this.scriptSourceField] === TaskStepModel.scriptStep.TYPE_SOURCE_BUSINESS
          ? I18n.t('新建业务脚本')
          : I18n.t('新建公共脚本');
      },
      /**
       * @desc 表单想验证规则
       * @returns { Array }
       *
       * 引用类型的脚本时 scriptId 不能为空
       */
      rules() {
        if (this.isScriptRefer) {
          return [{
            required: true,
            message: I18n.t('请选择引用脚本'),
            trigger: 'blur',
          }];
        }
        return [];
      },
    },
    watch: {
      formData: {
        handler() {
          this.initScriptSource();
        },
        immediate: true,
      },
      'formData.scriptId'(value) {
        if (value) {
          this.$refs.scriptId.clearValidator();
        }
      },
    },
    created() {
      if (this.formData[this.scriptVersionIdField]) {
        this.handleScriptVersionIdChange(this.formData[this.scriptVersionIdField]);
      }
      this.fetchScriptList();
      this.fetchPublicScriptList();
    },
    methods: {
      /**
       * @desc 获取业务脚本列表
       */
      fetchScriptList() {
        ScriptService.getOnlineScriptList()
          .then((data) => {
            this.scripList = data;
          });
      },
      /**
       * @desc 获公共脚本列表
       */
      fetchPublicScriptList() {
        PublicScriptService.getOnlineScriptList()
          .then((data) => {
            this.publicScripList = data;
          });
      },
      /**
       * @desc 初始化脚本来源
       */
      initScriptSource() {
        if (this.formData[this.scriptSourceField] === TaskStepModel.scriptStep.TYPE_SOURCE_LOCAL) {
          this.scriptSource = 'local';
          return;
        }
        this.scriptSource = 'refer';
        // 如果是引用脚本，还需初始化引用类型
        this.referType = this.formData[this.scriptSourceField];
      },
      handleClick() {
        this.fetchScriptList();
        this.fetchPublicScriptList();
      },
      /**
       * @desc 更新脚本来源
       * @param {String} source 脚本来源
       */
      handleScriptSourceChange(source) {
        // 脚本来源改变重置脚本相关的信息
        const scriptSource = source === 'local'
          ? TaskStepModel.scriptStep.TYPE_SOURCE_LOCAL
          : TaskStepModel.scriptStep.TYPE_SOURCE_BUSINESS;
        this.$emit('on-reset', {
          [this.scriptSourceField]: scriptSource,
          [this.scriptIdField]: '',
          [this.scriptVersionIdField]: '',
        });
      },
      /**
       * @desc 更新脚本引用来源类型
       * @param {String} scriptSource 脚本引用来源类型
       */
      handleReferScriptTypeChange(scriptSource) {
        if (scriptSource === this.formData[this.scriptSourceField]) {
          return;
        }
        this.$emit('on-reset', {
          [this.scriptSourceField]: scriptSource,
          [this.scriptIdField]: '',
          [this.scriptVersionIdField]: '',
        });
      },
      /**
       * @desc 更新脚本引用版本
       * @param {String} scriptVersionId 脚本引用来源类型
       */
      handleScriptVersionIdChange(scriptVersionId) {
        if (!scriptVersionId) {
          return;
        }

        this.$emit('on-reset', {
          isScriptContentLoading: true,
        });
        ScriptService.versionDetail({
          id: scriptVersionId,
        }).then(({ id, content, type, publicScript }) => {
          let scriptSource = TaskStepModel.scriptStep.TYPE_SOURCE_BUSINESS;
          if (publicScript) {
            scriptSource = TaskStepModel.scriptStep.TYPE_SOURCE_PUBLIC;
          }
          this.$emit('on-reset', {
            [this.scriptSourceField]: scriptSource,
            [this.scriptIdField]: id,
            [this.contentField]: content,
            [this.languageField]: type,
            [this.scriptVersionIdField]: scriptVersionId,
          });
        })
          .finally(() => {
            this.$emit('on-reset', {
              isScriptContentLoading: false,
            });
          });
      },
      /**
       * @desc 跳转到选择的脚本版本详情
       */
      handleGoScriptDetail() {
        const routerName = this.formData[this.scriptSourceField] === TaskStepModel.scriptStep.TYPE_SOURCE_PUBLIC
          ? 'publicScriptVersion'
          : 'scriptVersion';

        const { href } = this.$router.resolve({
          name: routerName,
          params: {
            id: this.formData[this.scriptIdField],
          },
          query: {
            scriptVersionId: this.formData[this.scriptVersionIdField],
          },
        });

        window.open(href);
      },
      /**
       * @desc 跳转新建脚本页面
       */
      handleGoCreate() {
        const routerName = this.formData[this.scriptSourceField] === TaskStepModel.scriptStep.TYPE_SOURCE_PUBLIC
          ? 'createPublicScript'
          : 'createScript';

        const { href } = this.$router.resolve({
          name: routerName,
        });

        window.open(href);
      },
    },
  };
</script>
<style lang='postcss'>
  @import url("@/css/mixins/media");

  .script-source-of-execution {
    .script-source-item {
      .bk-radio-button-text {
        width: 120px;
        text-align: center;
      }
    }

    .refer-script-box {
      position: relative;
      display: flex;

      .refer-script-detail {
        position: absolute;
        top: 0;
        right: -40px;
        bottom: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 40px;
        font-size: 16px;
        color: #3a84ff;
        cursor: pointer;
      }

      .refer-script-list {
        width: calc(500px - 120px);

        @media (--small-viewports) {
          width: calc(500px - 120px);
        }

        @media (--medium-viewports) {
          width: calc(560px - 120px);
        }

        @media (--large-viewports) {
          width: calc(620px - 120px);
        }

        @media (--huge-viewports) {
          width: calc(680px - 120px);
        }
      }
    }
  }
</style>
